voicemeeter\interface\callback/
commands.rs1use crate::{bindings::VBVMR_CBCOMMAND, types::VoicemeeterApplication};
5
6use super::data::{
7 AudioBuffer, AudioInfo, BufferInData, BufferMainData, BufferOutData, RawCallbackData,
8};
9
10macro_rules! implement {
11 (@audio_info $($name:ident),* $(,)?) => {
12 $(
13 impl HasAudioInfo for $name<'_> {
14 fn get(&self) -> &AudioInfo {
15 self.info
16 }
17 }
18 )*
19 };
20 (@audio_buffer $($name:ident),* $(,)?) => {
21 };
32}
33
34implement! { @audio_info
35 Starting,
36 Ending,
37 Change,
38}
39
40implement! { @audio_buffer
41 BufferIn,
42 BufferOut,
43 BufferMain,
44}
45
46pub trait HasAudioInfo {
48 fn get(&self) -> &AudioInfo;
50}
51
52pub trait HasAudioBuffer {
54 fn get(&self) -> &AudioBuffer;
56}
57
58#[derive(Debug)]
62pub struct Starting<'a> {
63 pub info: &'a AudioInfo,
65}
66
67impl<'a> Starting<'a> {
68 pub(crate) fn new(info: &'a AudioInfo) -> Self {
71 Self { info }
72 }
73}
74
75#[derive(Debug)]
77pub struct Ending<'a> {
78 pub info: &'a AudioInfo,
80}
81
82impl<'a> Ending<'a> {
83 pub(crate) fn new(info: &'a AudioInfo) -> Self {
86 Self { info }
87 }
88}
89
90#[derive(Debug)]
92pub struct Change<'a> {
93 pub info: &'a AudioInfo,
95}
96
97impl<'a> Change<'a> {
98 pub(crate) fn new(info: &'a AudioInfo) -> Self {
101 Self { info }
102 }
103}
104
105pub struct BufferIn<'a> {
107 pub buffer: BufferInData<'a>,
109 pub sr: usize,
111 pub nbs: usize,
113 pub nbi: usize,
115 pub nbo: usize,
117}
118
119impl<'a> BufferIn<'a> {
120 pub(crate) fn new(program: VoicemeeterApplication, buffer: &'a mut AudioBuffer) -> Self {
122 Self {
123 sr: buffer.audiobuffer_sr as usize,
124 nbs: buffer.audiobuffer_nbs as usize,
125 nbi: buffer.audiobuffer_nbi as usize,
126 nbo: buffer.audiobuffer_nbo as usize,
127 buffer: BufferInData::new(program, buffer, buffer.audiobuffer_nbs as usize),
128 }
129 }
130}
131
132pub struct BufferOut<'a> {
134 pub sr: usize,
136 pub buffer: BufferOutData<'a>,
138 pub nbs: usize,
140 pub nbi: usize,
142 pub nbo: usize,
144}
145
146impl<'a> BufferOut<'a> {
147 pub(crate) fn new(program: VoicemeeterApplication, buffer: &'a mut AudioBuffer) -> Self {
149 Self {
150 sr: buffer.audiobuffer_sr as usize,
151 nbs: buffer.audiobuffer_nbs as usize,
152 nbi: buffer.audiobuffer_nbi as usize,
153 nbo: buffer.audiobuffer_nbo as usize,
154 buffer: BufferOutData::new(program, buffer, buffer.audiobuffer_nbs as usize),
155 }
156 }
157}
158
159pub struct BufferMain<'a> {
161 pub buffer: BufferMainData<'a>,
163 pub sr: usize,
165 pub nbs: usize,
167 pub nbi: usize,
169 pub nbo: usize,
171}
172
173impl<'a> BufferMain<'a> {
174 pub(crate) fn new(program: VoicemeeterApplication, buffer: &'a mut AudioBuffer) -> Self {
176 Self {
177 sr: buffer.audiobuffer_sr as usize,
178 nbs: buffer.audiobuffer_nbs as usize,
179 nbi: buffer.audiobuffer_nbi as usize,
180 nbo: buffer.audiobuffer_nbo as usize,
181 buffer: BufferMainData::new(program, buffer, buffer.audiobuffer_nbs as usize),
182 }
183 }
184}
185
186#[repr(i32)]
188#[cfg(feature = "interface")] #[allow(clippy::large_enum_variant)]
190pub enum CallbackCommand<'a> {
191 Starting(Starting<'a>),
196 Ending(Ending<'a>),
201 Change(Change<'a>),
205 BufferIn(BufferIn<'a>),
209 BufferOut(BufferOut<'a>),
213 BufferMain(BufferMain<'a>),
217 Other(VBVMR_CBCOMMAND, RawCallbackData),
219}
220
221impl<'a> CallbackCommand<'a> {
222 #[doc(hidden)]
224 pub unsafe fn new_unchecked(
225 program: VoicemeeterApplication,
226 command: VBVMR_CBCOMMAND,
227 ptr: RawCallbackData,
228 ) -> Self {
229 match command {
230 VBVMR_CBCOMMAND::STARTING => {
231 Self::Starting(Starting::new(unsafe { ptr.as_audio_info() }))
232 }
233 VBVMR_CBCOMMAND::ENDING => Self::Ending(Ending::new(unsafe { ptr.as_audio_info() })),
234 VBVMR_CBCOMMAND::CHANGE => Self::Change(Change::new(unsafe { ptr.as_audio_info() })),
235 VBVMR_CBCOMMAND::BUFFER_IN => {
236 Self::BufferIn(BufferIn::new(program, unsafe { ptr.as_audio_buffer() }))
237 }
238 VBVMR_CBCOMMAND::BUFFER_OUT => {
239 Self::BufferOut(BufferOut::new(program, unsafe { ptr.as_audio_buffer() }))
240 }
241 VBVMR_CBCOMMAND::BUFFER_MAIN => {
242 Self::BufferMain(BufferMain::new(program, unsafe { ptr.as_audio_buffer() }))
243 }
244 i => Self::Other(i, ptr),
245 }
246 }
247
248 pub fn name(&self) -> Option<&'static str> {
250 Some(match self {
251 Self::Starting(_) => "Starting",
252 Self::Ending(_) => "Ending",
253 Self::Change(_) => "Change",
254 Self::BufferIn(_) => "BufferIn",
255 Self::BufferOut(_) => "BufferOut",
256 Self::BufferMain(_) => "BufferMain",
257 Self::Other(_, _) => return None,
258 })
259 }
260}